using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GemTowerDefence
{
  /// <summary>
  /// This class provides helper functions for making sprites, which are pixel based
  /// get drawn in correct positions and sizes when a window is resized.
  /// For the purposes of this code 1280x720 HD resolution is considered the base 
  /// size. Everything is sized based on its relative value to that.
  /// </summary>
  public class RelativeSpriteBatch : SpriteBatch
  {
    private const int FullHeight = 1080;
    private const int FullWidth = 1920;
    private static float _scale;
    private static Vector2 _offset;

    /// <summary>
    /// Initializes a new instance of the <see cref="RelativeSpriteBatch"/> class.
    /// </summary>
    /// <param name="graphicsDevice">The graphics device where sprites will be 
    /// drawn.</param>
    public RelativeSpriteBatch(GraphicsDevice graphicsDevice)
      : base(graphicsDevice)
    {
      Resize();
    }

    /// <summary>
    /// Adjust the scale and location of the drawn graphics so that everything 
    /// fits on the screen and is centered.
    /// </summary>
    public void Resize()
    {
      // Scale is used to stretch or shrink the drawn images so that everything
      // is visible on screen.
      _scale =
        Math.Min(GraphicsDevice.Viewport.Height / (float)FullHeight,
                 GraphicsDevice.Viewport.Width / (float)FullWidth);
      // The offset used to center the drawn images on the screen
      _offset =
        new Vector2((GraphicsDevice.Viewport.Width - FullWidth * _scale) / 2,
                    (GraphicsDevice.Viewport.Height - FullHeight * _scale) / 2);
    }

    /// <summary>
    /// Draws a sprite at a particular position
    /// </summary>
    /// <param name="texture">The texture to take the sprite from. For this overload
    /// it will draw the entire texture.</param>
    /// <param name="position">The position in 1280x720 screen space. It will 
    /// actually be drawn in the correct relative position and size</param>
    /// <param name="color">The color to tint the sprite</param>
    public new void Draw(Texture2D texture, Vector2 position, Color color)
    {
      Draw(texture, position, null, color);
    }

    /// <summary>
    /// Draws a sprite at a particular position
    /// </summary>
    /// <param name="texture">The texture to take the sprite from. For this overload
    /// it will draw the entire texture.</param>
    /// <param name="position">The position in 1280x720 screen space. It will 
    /// actually be drawn in the correct relative position and size</param>
    /// <param name="source">The part of the texture to draw</param>
    /// <param name="color">The color to tint the sprite</param>
    public new void Draw(Texture2D texture, Vector2 position, Rectangle? source,
                         Color color)
    {
      //Scale and move the sprite based on current screen size 
      Draw(texture, (position * _scale) + _offset, source, color, 0,
                Vector2.Zero, _scale, SpriteEffects.None, 0);
    }
  }
}